package org.gary.base.action;

import static lengreen.util.constant.Constant.DateFomaterString.YYYY_MM_DD_HH_MM_SS;
import static org.gary.core.util.Utils.*;

import java.io.IOException;
import java.net.URLDecoder;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;

import lengreen.core.interfaces.Entity;

import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import net.sf.json.JsonConfig;

import org.apache.struts2.interceptor.ServletResponseAware;
import org.apache.struts2.interceptor.SessionAware;
import org.gary.base.model.Category;
import org.gary.base.service.CategoryService;
import org.gary.base.service.ImageService;
import org.gary.base.service.XxxImageService;
import org.gary.core.dto.CategoryDto;
import org.gary.core.service.InitService;
import org.gary.equipment.model.Equipment;
import org.gary.equipment.service.EquipmentService;
import org.gary.news.model.News;
import org.gary.news.service.NewsService;
import org.gary.product.model.Product;
import org.gary.product.service.ProductService;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;

import com.opensymphony.xwork2.ActionSupport;

/**
 * 
 * @author lengreen
 * 
 */
@Component
@Scope("prototype")
public class CategoryAction extends ActionSupport implements
		ServletResponseAware, SessionAware {
	private static final long serialVersionUID = 3444571883909828228L;
	private HttpServletResponse response;
	private Map<String, Object> session;

	private CategoryService categoryService;
	private ProductService productService;
	private NewsService newsService;
	private EquipmentService equipmentService;
	private XxxImageService xxxImageService;
	private ImageService imageService;
	private InitService initService;

	private Category category;
	private List<Category> categoryList;
	/**类别主人*/
	private String whoCategory;
	/**类别语言类型*/
	private String lang;
	/**父亲id*/
	private String parentId;
	/**是否可见*/
	private String visible;
	/**分页开始*/
	private int start;
	/**分页最大记录*/
	private int limit;
	/**查找类别名称*/
	private String categoryName;
	/**查找开始时间*/
	private String fromDate;
	/**结束时间*/
	private String toDate;
	/**删除模式*/
	private String mode;
	/**结果字符串*/
	private String result = "";

	/**
	 * 获取一个category for has categories
	 * @throws Exception
	 */
	public void list() throws Exception {
		for (Object[] category : categoryService.list(getWhoCategory(),
				getLang())) {
			result += "['" + category[0].toString() + "','"
					+ category[1].toString() + "']" + ",";
		}
		result = "[" + result.substring(0, result.length() - 1) + "]";
		response.setCharacterEncoding("utf-8");
		response.getWriter().write(result);
	}

	/**
	 * 列出所有顶级类别
	 * @throws Exception
	 */
	public void listParent() throws Exception {
		for (Object[] category : categoryService.listParent(getWhoCategory(),
				getLang())) {
			result += "['" + category[0].toString() + "','"
					+ category[1].toString() + "']" + ",";
		}
		result = "[" + result.substring(0, result.length() - 1) + "]";
		response.setCharacterEncoding("utf-8");
		response.getWriter().write(result);
	}
	
	/**
	 * 检查当前添加的category name是否存在
	 * @throws Exception
	 */
	public void checkExist() throws Exception {
		try{
			categoryName = URLDecoder.decode(categoryName, "UTF-8");
		if(categoryService.checkNameExist(categoryName, lang)) {
			result = "{'result':'true'}";
		} else {
			result = "{'result':'false'}";
		}
		response.setCharacterEncoding("utf-8");
		response.getWriter().write(result);
		}catch(Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * 增加一个类别
	 * @throws IOException
	 */
	public void add() throws IOException {
		if (category != null) {
			if (!"".equals(parentId)) {
				Category parent = categoryService.load(Category.class, Integer
						.parseInt(parentId));
				category.setParent(parent);
			}
			categoryService.save(category);
			initService.updateNavigation(session);
			result = "{'success':'true'}";
		} else {
			result = "{'success':'false'}";
		}
		response.setCharacterEncoding("utf-8");
		response.getWriter().write(result);
	}

	/**
	 * 列出所有类别
	 * @throws IOException
	 */
	public void listAll() throws IOException {
		start = parseIndex(start, limit);
		Map<String, Object> where = new HashMap<String, Object>();
		where.put(" entity.visible = ", new Boolean(getVisible()));
		setCategoryList(categoryService.list(Category.class, start,
				limit, where, new Object[] { " entity.id desc " }));

		JsonConfig config = makeDateFormateJsonConfig(YYYY_MM_DD_HH_MM_SS);
		config.setExcludes(new String[]{"parent", "visible", "children"});
		JSONArray categoryListJsonArray = JSONArray.fromObject(categoryList, config);
		JSONObject categoryJsonObject = new JSONObject();
		categoryJsonObject.put("categoryTotal", categoryService
				.selectTotalCount(null));
		categoryJsonObject.put("categoryList", categoryListJsonArray);
		response.setCharacterEncoding("utf-8");
		response.getWriter().write(categoryJsonObject.toString());
	}

	/**
	 * 查找
	 * @throws IOException
	 */
	public void search() throws IOException {
		start = parseIndex(start, limit);
		Map<String, Object> where = new HashMap<String, Object>();
		where.put(" entity.visible = ", new Boolean(getVisible()));

		System.out.println("categoryName-->" + categoryName);
		System.out.println("fromDate-->" + fromDate);
		System.out.println("toDate-->" + toDate);

		if (!"".equals(categoryName.trim())) {
			where.put(" entity.name like ", categoryName);
		}
		if (!"".equals(fromDate.trim())) {
			if ("".equals(toDate.trim())) {
				where.put(" entity.createDate between ", fromDate
						+ " 00:00:00' and '"
						+ getFormatDate(new Date(), YYYY_MM_DD_HH_MM_SS));
			} else {
				where.put(" entity.createDate between ", fromDate
						+ " 00:00:00' and '" + toDate + " 23:59:59");
			}
		}
		if (!"".equals(lang.trim())) {
			where.put(" entity.lang = ", lang);
		}

		setCategoryList(categoryService.list(Category.class, start, limit,
				where, new Object[] { " entity.id desc " }));

		JsonConfig config = makeDateFormateJsonConfig(YYYY_MM_DD_HH_MM_SS);
		config.setExcludes(new String[]{"parent", "visible", "children"});
		JSONArray categoryListJsonArray = JSONArray.fromObject(categoryList, config);
		JSONObject categoryJsonObject = new JSONObject();
		categoryJsonObject.put("categoryTotal", categoryService
				.selectTotalCount(null));
		categoryJsonObject.put("categoryList", categoryListJsonArray);
		response.setCharacterEncoding("utf-8");
		response.getWriter().write(categoryJsonObject.toString());
	}

	/**
	 * 加载
	 * @throws IOException
	 */
	public void load() throws IOException {
		Category p = categoryService.load(Category.class, category.getId());
		JsonConfig config = makeDateFormateJsonConfig(YYYY_MM_DD_HH_MM_SS);
		JSONObject categoryJsonObject = JSONObject.fromObject(p, config);
		response.setCharacterEncoding("utf-8");
		response.getWriter().write(categoryJsonObject.toString());
	}

	/**
	 * 更新
	 * @throws IOException
	 */
	public void update() throws IOException {
		try {
		if (category != null) {
			Category ctemp = categoryService.load(Category.class, category.getId());
			if(!"".equals(parentId)) {
				ctemp.setParent(categoryService.load(Category.class, Integer.parseInt(parentId)));
			} else {
				List<Category> children = categoryService.children(ctemp.getId());
				if(children != null) {
					if(children.size() >= 1) {
						Set<Category> childrenSet = new HashSet<Category>();
						for(Category c : children) {
							childrenSet.add(c);
						}
						ctemp.setChildren(childrenSet);
					}
				}
			}
			ctemp.setLang(category.getLang());
			ctemp.setName(category.getName());
			ctemp.setNotes(category.getNotes());
			categoryService.update(ctemp);
			initService.updateNavigation(session);
			result = "{'success':'true'}";
		} else {
			result = "{'success':'false'}";
		}
		response.setCharacterEncoding("utf-8");
		response.getWriter().write(result);
		}catch(Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * 删除之前列出关联记录
	 * @throws Exception
	 */
	public void preDelete() throws Exception {
		try {
			List<CategoryDto> result = null;
			JSONObject jsonObject = new JSONObject();
			JSONArray jsonArray = null;
			if ("product".equalsIgnoreCase(getWhoCategory())) {
				result = categoryService.preDelete(category.getId(), Product.class);
			} else if ("equipment".equalsIgnoreCase(getWhoCategory())) {
				result = categoryService.preDelete(category.getId(), Equipment.class);
			} else if ("news".equalsIgnoreCase(getWhoCategory())) {
				result = categoryService.preDelete(category.getId(), News.class);
			}
			if (result != null) {
				jsonArray = JSONArray.fromObject(result);
				jsonObject.put("msg", "has");
			} else {
				jsonObject.put("msg", "none");
			}
			jsonObject.put("list", jsonArray);
			System.out.println("preDeleteCategory-->" + jsonObject.toString());
			response.setCharacterEncoding("utf-8");
			response.getWriter().write(jsonObject.toString());
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * 回收
	 */
	public void recover() {
		try {
			if (category != null) {
				Class<? extends Entity> entity = null;
				if ("product".equalsIgnoreCase(getWhoCategory())) {
					entity = Product.class;
				} else if ("equipment".equalsIgnoreCase(getWhoCategory())) {
					entity = Equipment.class;
				} else if ("news".equalsIgnoreCase(getWhoCategory())) {
					entity = News.class;
				}
				List<Category> children = categoryService.children(category.getId());
				
				if (children != null) {
					if (children.size() >= 1) {
						for (Category c : children) {
							updateUtil(entity, c.getId(), true);
							categoryService.update(Category.class, new Object[]{c.getId()}, true);
						}
					}
				}
				updateUtil(entity, category.getId(), true);
				categoryService.update(Category.class, new Object[]{category.getId()}, true);
				initService.updateNavigation(session);
				result = "{'success':'true'}";
			} else {
				result = "{'success':'false'}";
			}
			response.setCharacterEncoding("utf-8");
			response.getWriter().write(result);
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	/**
	 * 删除
	 * @throws IOException
	 */
	public void delete() throws IOException {
		System.out.println("delete config-->" + category.getId() + '-' + getWhoCategory() + '-' + getMode()); 
		try {
			Class<? extends Entity> entity = null;
			if ("product".equalsIgnoreCase(getWhoCategory())) {
				entity = Product.class;
			} else if ("equipment".equalsIgnoreCase(getWhoCategory())) {
				entity = Equipment.class;
			} else if ("news".equalsIgnoreCase(getWhoCategory())) {
				entity = News.class;
			}
			List<Category> children = categoryService.children(category.getId());
			
			if ("delete".equals(getMode())) {
				if (children != null) {
					if (children.size() >= 1) {
						for (Category c : children) {
							deleteUtil(entity, c.getId());
							categoryService.delete(c);
						}
					}
				}
				deleteUtil(entity, category.getId());
				categoryService.delete(categoryService.load(Category.class, category.getId()));
				initService.updateNavigation(session);
				result = "{'result':'delete'}";
			} else if ("update".equals(getMode())) {
				if (children != null) {
					if (children.size() >= 1) {
						for (Category c : children) {
							updateUtil(entity, c.getId(), false);
							categoryService.update(Category.class, new Object[]{c.getId()}, false);
						}
					}
				}
				updateUtil(entity, category.getId(), false);
				categoryService.update(Category.class, new Object[] { category
						.getId() }, false);
				initService.updateNavigation(session);
				result = "{'result':'update'}";
			} else {
				result = "{'result':'none'}";
			}
			response.setCharacterEncoding("utf-8");
			response.getWriter().write(result);
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	/**
	 * 删除方法
	 * @param entity
	 * @param cid
	 */
	private synchronized void deleteUtil(Class<? extends Entity> entity, int cid) {
		try{
		List<? extends Entity> xxxList = categoryService.loadXxxByCategory(
				entity, cid);
		if (xxxList.size() > 0) {
			for (Entity e : xxxList) {
				if(entity.equals(Product.class)) {
					productService.delete(e);
				} else if(entity.equals(Equipment.class)) {
					equipmentService.delete(e);
				} else if(entity.equals(News.class)) {
					newsService.delete(e);
				}
			}
		}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	/**
	 * 更新方法
	 * @param entity
	 * @param cid
	 * @param visible 更新可见性来实现
	 */
	private synchronized void updateUtil(Class<? extends Entity> entity, int cid, boolean visible) {
		try{
			List<? extends Entity> xxxList = categoryService.loadXxxByCategory(
					entity, cid);
			if (xxxList.size() > 0) {
				for (Entity e : xxxList) {
					if(entity.equals(Product.class)) {
						productService.update(Product.class, new Object[]{e.getId()}, visible);
					} else if(entity.equals(Equipment.class)) {
						equipmentService.update(Equipment.class, new Object[]{e.getId()}, visible);
					} else if(entity.equals(News.class)) {
						newsService.update(News.class, new Object[]{e.getId()}, visible);
					}
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	@Resource
	public void setCategoryService(CategoryService categoryService) {
		this.categoryService = categoryService;
	}

	public CategoryService getCategoryService() {
		return categoryService;
	}

	@Override
	public void setServletResponse(HttpServletResponse response) {
		this.response = response;
	}

	public void setWhoCategory(String whoCategory) {
		this.whoCategory = whoCategory;
	}

	public String getWhoCategory() {
		return whoCategory;
	}

	public void setParentId(String parentId) {
		this.parentId = parentId;
	}

	public String getParentId() {
		return parentId;
	}

	public void setLang(String lang) {
		this.lang = lang;
	}

	public String getLang() {
		return lang;
	}

	public void setVisible(String visible) {
		this.visible = visible;
	}

	public String getVisible() {
		return visible;
	}

	public void setCategory(Category category) {
		this.category = category;
	}

	public Category getCategory() {
		return category;
	}

	public void setStart(int start) {
		this.start = start;
	}

	public int getStart() {
		return start;
	}

	public void setLimit(int limit) {
		this.limit = limit;
	}

	public int getLimit() {
		return limit;
	}

	public void setCategoryList(List<Category> categoryList) {
		this.categoryList = categoryList;
	}

	public List<Category> getCategoryList() {
		return categoryList;
	}

	public void setCategoryName(String categoryName) {
		this.categoryName = categoryName;
	}

	public String getCategoryName() {
		return categoryName;
	}

	public void setFromDate(String fromDate) {
		this.fromDate = fromDate;
	}

	public String getFromDate() {
		return fromDate;
	}

	public void setToDate(String toDate) {
		this.toDate = toDate;
	}

	public String getToDate() {
		return toDate;
	}

	public void setMode(String mode) {
		this.mode = mode;
	}

	public String getMode() {
		return mode;
	}

	@Resource
	public void setProductService(ProductService productService) {
		this.productService = productService;
	}

	public ProductService getProductService() {
		return productService;
	}

	@Resource
	public void setXxxImageService(XxxImageService xxxImageService) {
		this.xxxImageService = xxxImageService;
	}

	public XxxImageService getXxxImageService() {
		return xxxImageService;
	}

	@Resource
	public void setImageService(ImageService imageService) {
		this.imageService = imageService;
	}

	public ImageService getImageService() {
		return imageService;
	}

	@Resource
	public void setNewsService(NewsService newsService) {
		this.newsService = newsService;
	}

	public NewsService getNewsService() {
		return newsService;
	}

	@Resource
	public void setEquipmentService(EquipmentService equipmentService) {
		this.equipmentService = equipmentService;
	}

	public EquipmentService getEquipmentService() {
		return equipmentService;
	}

	@Override
	public void setSession(Map<String, Object> arg0) {
		this.session = arg0;
	}

	@Resource
	public void setInitService(InitService initService) {
		this.initService = initService;
	}

	public InitService getInitService() {
		return initService;
	}

}
